package com.mycompany.project.client.duch;

import java.util.Date;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.mycompany.project.client.chee.MHCSound;



/**
 * This class acts as the graphical user interface
 * for the rover calibration class.
 * @author Timothy Duch
 */
public class RoverCalibrationGUI {
    /**
     * Flag to see whether we should check
     * if an initial rover calibration
     * has taken place.
     */
    private static boolean initCal = true;
    /**
     * Flag to see whether we should check
     * if the rover has been calibrated in the
     * past 10 days.
     */
    private static boolean constCal = true;
    /**
     * Timer to control checking alerts.
     */
    private static Timer alertTimer;
    /**
     * Logic underlying the GUI.
     */
    private final transient static RoverCalibration roverCal = new RoverCalibration();
    /**
     * Panel containing the button and label.
     */
    private static final HorizontalPanel HPANEL = new HorizontalPanel();
    /**
     * Label containing the date of the last calibration.
     */
    private final transient static Label roverLbl = new Label();
    /**
     * Number representing a 30 second schedule.
     */
    private static final int SCHEDULEDTIME = 45000;
    /**
     * Number representing the maximum days
     * the rover can go without calibration.
     */
    private static final int MAXDAYS = 10;

    /**
     * Initialize the timer and GUI.
     */
    public static void initRoverCalibration() {
    alertTimer = new Timer() {

            @Override
            public void run() {
                if (isInitCal()) {
                checkInitialCalibration();
                }
                if (isConstCal()) {
                    checkConstantCalibration();
                }
            }
        };
        //repeats every 30 seconds
        alertTimer.scheduleRepeating(SCHEDULEDTIME);
        HPANEL.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT);
        HPANEL.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
        HPANEL.setWidth("500px");

        final Button calButton = new Button("Calibrate Rover Milometer");
        calButton.addClickHandler(new ClickHandler() {
            public void onClick(final ClickEvent event) {
                roverCal.setDate(new Date());
                roverLbl.setText("Last Calibrated:   "
                        + getRoverCal().getStringDate());
                setConstCal(true);

            }
        });

        HPANEL.add(calButton);

        if (getRoverCal().getStringDate() == null) {
            getRoverLbl().setText("Rover has not been Calibrated!");
        } else {
            getRoverLbl().setText("Last Calibrated:   "
        + getRoverCal().getStringDate());
        }

        HPANEL.add(getRoverLbl());
    }

    /**
     * Returns the Horizontal panel.
     * @return HorizontalPanel is the VeritcalPanel of the class.
     */
    public static final HorizontalPanel getGUI() {
        return HPANEL;
    }

    /**
     * Checks to see if the rover has been
     * initially calibrated. If it hasn't,
     * the flag will turn false, and the timer will no longer
     * check for initial calibration alert.
     */
    public static void checkInitialCalibration() {
        if (roverCal.getStringDate() == null) {
            Window.alert("Rover has not been Calibrated!");
            setInitCal(false);
        }
    }

    /**
     * Checks to see if the rover has been calibrated within the past 10 days.
     * If it hasn't, the flag will turn false, and the timer will no longer
     * check for the calibration, until the button is pressed.
     */
    public static void checkConstantCalibration() {
        if (getRoverCal().daysElapsed() != -1 && getRoverCal().daysElapsed()
                > MAXDAYS) {
        	MHCSound.playTenDays();
            Window.alert("It has been more than 10 "
                    + "days since the rover milometer has been calibrated!");
            setConstCal(false);
        }
    }

    /**
     * Returns the instantiation flag for the calibration date.
     * @return initCal is the flag for instantiation.
     */
    private static boolean isInitCal() {
        return initCal;
    }

    /**
     * Sets the instantiation flag for the calibration date.
     * @param tempInitCal is the flag for instantiation.
     */
    private static void setInitCal(final boolean tempInitCal) {
        initCal = tempInitCal;
    }

    /**
     * Returns the flag for the calibration date being over 10 days since last.
     * @return constCal is the over 10 days flag.
     */
    private static boolean isConstCal() {
        return constCal;
    }

    /**
     * Sets the flag for the calibration date being over 10 days since last.
     * @param tempConstCal is the over 10 days flag.
     */
    private static void setConstCal(final boolean tempConstCal) {
        constCal = tempConstCal;
    }

    /**
     * Gets the rover calibration date.
     * @return roverCal is the calibration date.
     */
    private static RoverCalibration getRoverCal() {
        return roverCal;
    }

    /**
     * Gets the label containing the calibration date.
     * @return roverLbl is the label containing the calibration date.
     */
    private static Label getRoverLbl() {
        return roverLbl;
    }

}
